﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor.Experimental.GraphView;


public class EcsRecordSystem<T> : ECSRecordSystemBase where T : ECSMomentCompoentBase, new()
{
    /// <summary>
    /// 网络同步组件列表
    /// </summary>
    public List<T> RecordMomentCom=new List<T>();
    /// <summary>
    /// 哈希为网络同步组件的类型名转索引
    /// </summary>
    private int hashCode = 0;

    #region 获取泛型网络同步组件的类型,Filter过滤器
    public override Type[] GetFilter()
    {
        return new Type[] { typeof(T) };
    }
    #endregion

    public override void OnInit()
    {
        hashCode = ToIndex(typeof(T).Name);
    }

    public override void ClearAll()
    {
       RecordMomentCom.Clear();
    }

    public override void ClearBefore(int frame)
    {
        ECSMomentCompoentBase thisRec = null;
        for (int i = 0, j = RecordMomentCom.Count; i < j; i++)
        {
            thisRec = RecordMomentCom[i];
            if (thisRec.Frame < frame)
            {
                RecordMomentCom.RemoveAt(i);
                i--;
                j--;
            }
        }
    }

    public override void ClearRecordAt(int frame)
    {
        ECSMomentCompoentBase thisRec = null;
        for (int i = 0, j = RecordMomentCom.Count; i < j; i++)
        {
            thisRec = RecordMomentCom[i];
            if ( thisRec.Frame == frame)
            {
                RecordMomentCom.RemoveAt(i);
                i--;
                j--;
            }
        }
    }

    public override void ClearAfter(int frame)
    {
        ECSMomentCompoentBase thisRec = null;
        for (int i = 0, j = RecordMomentCom.Count; i < j; i++)
        {
            thisRec = RecordMomentCom[i];
            if (thisRec.Frame > frame)
            {
                RecordMomentCom.RemoveAt(i);
                i--;
                j--;
            }
        }
    }

    public override void PrintRecord(int id)
    {
        throw new NotImplementedException();
    }
    /// <summary>
    /// 拷贝该帧的对应的网络片刻组件到列表中
    /// </summary>
    /// <param name="frame"></param>
    public override void Record(int frame)
    {
        //从组管理器中过去带有该T的实体
        List<ECSEntityBase> thisList = GetEntityList();
        for (int i = 0,j=thisList.Count; i < j; i++)
        {
            ECSEntityBase entity = thisList[i];
            T data = entity.GetCom<T>(hashCode);
            data.IsChange = false;

            T record = (T) data.DeepCopy();
            record.Frame = frame;
            record.ID = entity.ID;
            record.World = entity.World;

            RecordMomentCom.Add(record);
        }
    }

    public override ECSMomentCompoentBase GetRecord(int id, int frame)
    {
        ECSMomentCompoentBase thisRec = null;
        for (int i = 0,j=RecordMomentCom.Count; i < j; i++)
        {
            thisRec = RecordMomentCom[i];
            if (thisRec.ID==id&&thisRec.Frame==frame)
            {
                return thisRec;
            }
        }

        return null;
    }

    public override void RevertToFrame(int frame)
    {
        int thisId;
        ECSEntityBase entity;
        for (int i = 0,j=RecordMomentCom.Count; i < j; i++)
        {
            T record = RecordMomentCom[i];
            if (record.Frame==frame)
            {
                thisId = record.ID;
                if (MyWorld.GetEntityIsExist(thisId))
                {
                     entity = MyWorld.GetEntity(thisId);
                    entity.ChangeCom(hashCode,(T)record.DeepCopy());
                }
                else if (MyWorld.GetIsExistDispatchDestoryCache(thisId))
                {
                    entity = MyWorld.GetDispatchDestoryCache(thisId);
                    entity.ChangeCom(hashCode, (T)record.DeepCopy());
                }
                else if (MyWorld.GetIsExistDispatchCreateCache(thisId))
                {
                    entity = MyWorld.GetDispatchCreateCache(thisId);
                    entity.ChangeCom(hashCode, (T)record.DeepCopy());
                }
                else
                {
                    throw new Exception("无法找到回滚实体，实体id："+thisId);
                }
                RecordMomentCom.RemoveAt(i);
                i--;
                j--;
            }
        }
    }
}

